package com.sskj.api.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sskj.api.domain.Permission;
import com.sskj.api.domain.Role;
import com.sskj.api.domain.SysUser;
import com.sskj.api.exception.LogicException;
import com.sskj.api.mapper.SysUserMapper;
import com.sskj.api.service.IPermissionService;
import com.sskj.api.service.IRolePermissionService;
import com.sskj.api.service.ISysUserService;
import com.sskj.api.service.IUserRoleService;
import com.sskj.api.vo.req.AdminUserAddReq;
import com.sskj.api.vo.req.SysUserPageListReq;
import com.sskj.common.dto.TreeNode;
import com.sskj.common.util.PasswordUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
public class SysUserService extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Autowired
    private IUserRoleService userRoleService;

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private IRolePermissionService rolePermissionService;

    @Override
    public SysUser accountLogin(String phone, String password) {
        SysUser sysUser = getByPhone(phone);
        if (sysUser == null) {
            throw new LogicException("手机号或密码不正确");
        }
        if (sysUser.getStatus() != 1) {
            throw new LogicException("用户状态异常，禁止登录");
        }
        if (!PasswordUtil.checkPassword(password, sysUser.getPassword())) {
            throw new LogicException("手机号或密码不正确");
        }
        return sysUser;
    }

    @Override
    public SysUser getByPhone(String phone) {
        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysUser::getPhone, phone);
        return getOne(lambdaQueryWrapper);
    }

    @Override
    public SysUser info(Long id) {
        SysUser sysUser = getById(id);
        if (sysUser != null) {
            sysUser.setRoles(userRoleService.listByUserId(id));
        }
        return sysUser;
    }

    @Override
    public IPage<SysUser> pageList(SysUserPageListReq req) {
        Page<SysUser> pageConfig = new Page<>(req.getPageNum(), req.getPageSize());

        return baseMapper.pageList(pageConfig, req);
    }

    @Override
    @Transactional
    public void add(AdminUserAddReq req) {
        SysUser sysUser = getByPhone(req.getPhone());
        if (sysUser != null) {
            throw new LogicException("手机号已存在");
        }

        SysUser newSysUser = new SysUser();
        newSysUser.setPhone(req.getPhone());
        newSysUser.setName(req.getName());
        newSysUser.setPassword(PasswordUtil.encryptPassword(req.getPassword()));
        newSysUser.setStatus(1);
        newSysUser.setDepartmentId(req.getDepartmentId());
        newSysUser.setPositionId(req.getPositionId());

        if(save(newSysUser)) {
            if (req.getRoleIds() != null && !req.getRoleIds().isEmpty()) {
                userRoleService.bindRoles(newSysUser.getId(), req.getRoleIds());
            }
        }
    }

    @Override
    public Long countByDepartmentId(Long departmentId) {
        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysUser::getDepartmentId, departmentId);
        return count(lambdaQueryWrapper);
    }

    @Override
    public Long countByPositionId(Long positionId) {
        LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysUser::getPositionId, positionId);
        return count(lambdaQueryWrapper);
    }

    @Override
    public List<TreeNode<Permission>> getMenus(Long id) {
        Boolean isAdmin = userRoleService.isAdmin(id);
        if (isAdmin) {
            return permissionService.tree(-1);
        } else {
            List<Role> roles = userRoleService.listByUserId(id);
            if (roles != null && !roles.isEmpty()) {
                List<Long> roleIds = roles.stream().map(Role::getId).toList();
                return rolePermissionService.treeByRoleIds(roleIds);
            }
        }
        return null;
    }

    @Override
    public List<Permission> getActionPermission(Long id) {
        Boolean isAdmin = userRoleService.isAdmin(id);
        if (isAdmin) {
            return permissionService.allAction();
        } else {
            List<Role> roles = userRoleService.listByUserId(id);
            if (roles != null && !roles.isEmpty()) {
                List<Long> roleIds = roles.stream().map(Role::getId).toList();
                Set<Long> permissionIds = rolePermissionService.listPermissionByRoleIds(roleIds);
                return permissionService.listAction(permissionIds);
            }
        }
        return List.of();
    }

    @Override
    public void resetPassword(Long userId) {
        long loginUserId = StpUtil.getLoginIdAsLong();
        if (loginUserId != userId && userId != 1) {
            SysUser sysUser = getById(userId);
            if (sysUser != null) {
                sysUser.setPassword(PasswordUtil.encryptPassword("123456"));
                sysUser.setUpdateTime(LocalDateTime.now());

                updateById(sysUser);
            }
        }
    }

    @Override
    public Boolean modifyPassword(Long userId, String oldPassword, String newPassword) {
        SysUser sysUser = getById(userId);
        if (sysUser != null) {
            if (!PasswordUtil.checkPassword(oldPassword, sysUser.getPassword())) {
                throw new LogicException("旧密码错误，中止操作");
            }

            sysUser.setPassword(PasswordUtil.encryptPassword(newPassword));
            sysUser.setUpdateTime(LocalDateTime.now());

            return updateById(sysUser);
        }
        return false;
    }
}
